﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.Globalization;
using System.Reflection;
using System.Text;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Expression.Entity;
using T.FAS.Runtime.Expression.SPI;

namespace T.FAS.Runtime.Expression.Plugin
{
    public class AssertExecutor : DynamicObject, IDynamicActionAdapter
    {
        private void AreEqual<T>(T expected, T actual)
        {
            if (!object.Equals(expected, actual))
            {
                throw new FasException("AreEqual", "AreEqual");
            }
        }
        private void AreNotEqual<T>(T notExpected, T actual)
        {
            if (object.Equals(notExpected, actual))
            {
                throw new FasException("AreNotEqual", "AreNotEqual");
            }
        }
        /// <summary>
        /// JS脚本动态调用Dynamic必备函数
        /// 脚本写法：Assert.IsTrue(1==2);
        /// </summary>
        /// <param name="name">动态调用DynamicObject中的函数名称</param>
        /// <param name="args">参数信息，参数类型必须增加 params</param>
        /// <returns></returns>
        public dynamic DynamicInvoke(string name, params object[] args)
        {
            return ExcuteAssert(name, args);
        }

        private dynamic ExcuteAssert(string actionID, object[] paramList)
        {
            if (actionID == "IsTrue")
            {
                bool condition = bool.Parse(paramList[0].ToString());
                if (!condition)
                {
                    throw new FasException("IsTrue", "IsTrue");
                }
            }
            else if (actionID == "IsFalse")
            {
                bool condition = bool.Parse(paramList[0].ToString());
                if (condition)
                {
                    throw new FasException("IsFalse", "IsFalse");
                }
            }
            else if (actionID == "IsNotNull")
            {
                if (paramList[0] == null)
                {
                    throw new FasException("IsNotNull", "IsNotNull");
                }
            }
            else if (actionID == "IsNull")
            {
                if (paramList[0] != null)
                {
                    throw new FasException("IsNull", "IsNull");
                }
            }
            else if (actionID == "AreEqual")
            {
                AreEqual<object>(paramList[0], paramList[1]);
            }
            else if (actionID == "AreNotEqual")
            {
                AreNotEqual<object>(paramList[0], paramList[1]);
            }
            else
            {
                throw new FasException(ExprExceptionCode.NotSupported, "Unsupported Assert." + actionID);
            }
            return true;
        }

        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out dynamic result)
        {
            result = DynamicInvoke(binder.Name, args);
            return true;
        }
    }
}
